home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Speccy ClassiX 1998
/
Speccy ClassiX 98.iso
/
amiga_system
/
the_aminet
/
util
/
libs
/
halt.lzh
/
halt
/
sdwarn.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-10-06
|
7KB
|
312 lines
/*
sdwarn.c --- example shutdown client.
(c) Copyright 1995 SHW Wabnitz
Written by Bernhard Fastenrath (fasten@shw.com)
This file may be distributed under the terms
of the GNU General Public License.
*/
#include <dos.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <exec/types.h>
#include <proto/exec.h>
#include <proto/dos.h>
#if defined (__GNUC__)
#include "halt_inline.h"
#else
#include "halt_pragmas.h"
#endif
#include "halt.h"
#include "ups.h"
void CloseTimerDevice (void);
int CheckCLISession (void);
struct Library *HaltBase = NULL;
struct MsgPort *prt = NULL;
struct timerequest *TimerReq = NULL;
struct MsgPort *TimerPort = NULL;
ULONG TimerMask = 0;
ULONG CliNumber = 0;
BPTR CliStdout = NULL;
struct Process *MyProc;
APTR WindowPtr;
char *optarg = NULL;
int
getopt (int argc, char *argv[], char *opts)
{
static int pos = 0;
char *c;
while (++pos < argc && argv[pos][0] != '-');
if (pos >= argc)
return -1;
if ((c = strchr (opts, (int) argv[pos][1])) == 0)
return (int) '?';
if (*(c+1) != ':')
return (int) *c;
if (strlen (argv[pos]) > 2)
optarg = argv[pos] + 2;
else if (pos+1 < argc)
optarg = argv[pos+1];
else
return (int) '?';
return (int) *c;
}
#if !defined (__GNUC__)
int
SigBreakHandler (void)
{
struct Message *msg;
if (HaltBase)
{
if (prt)
{
Forbid ();
while (msg = GetMsg (prt))
ReplyMsg (msg);
RemShutdownPort (prt);
DeleteMsgPort (prt);
Permit ();
}
CloseTimerDevice ();
CloseLibrary (HaltBase);
}
exit (EXIT_SUCCESS);
return 0;
}
#endif
int
CheckCLISession ()
{
struct Process *pr;
int code = 0;
if (!CliNumber)
return 1;
Forbid ();
if (pr = FindCliProc (CliNumber))
{
/* We might have found a new CLI
with the same number.
*/
if (pr -> pr_COS == CliStdout)
code = 1;
}
Permit ();
return code;
}
void
CloseTimerDevice ()
{
if (!TimerPort)
return;
AbortIO ((struct IORequest *) TimerReq);
WaitIO ((struct IORequest *) TimerReq);
CloseDevice ((struct IORequest *) TimerReq);
DeleteIORequest (TimerReq);
DeleteMsgPort (TimerPort);
TimerPort = NULL;
}
void
StartTimer ()
{
if (TimerPort)
{
TimerReq -> tr_node.io_Command = TR_ADDREQUEST;
TimerReq -> tr_time.tv_secs = 3;
TimerReq -> tr_time.tv_micro = 0;
SendIO ((struct IORequest *) TimerReq);
}
}
ULONG
OpenTimerDevice ()
{
if (!(TimerPort = CreateMsgPort ()))
return 0;
if (!(TimerReq = (struct timerequest *)
CreateIORequest (TimerPort, sizeof (struct timerequest))))
{
DeleteMsgPort (TimerPort);
return 0;
}
if (OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *) TimerReq, 0))
{
DeleteIORequest (TimerReq);
DeleteMsgPort (TimerPort);
return 0;
}
StartTimer ();
return TimerMask = 1 << TimerPort -> mp_SigBit;
}
int
main (int argc, char *argv[])
{
ShutdownMessage *sm;
UpsInfo *ups;
char *UpsEvents[] = UPS_EV_NAMES;
int abort = 0;
int verbose = 0;
ULONG mask, rmask;
int opt;
#if !defined (__GNUC__)
onbreak (SigBreakHandler);
#endif
MyProc = (struct Process *) FindTask (0);
WindowPtr = MyProc -> pr_WindowPtr;
MyProc -> pr_WindowPtr = (void *) -1;
while ((opt = getopt (argc, argv, "ac:v")) != -1)
switch (opt)
{
case 'a': abort = 1; break;
case 'v': verbose = 1; break;
case 'c':
if (CliNumber = atoi (optarg))
{
struct Process *pr;
Forbid ();
if (pr = FindCliProc (CliNumber))
CliStdout = pr -> pr_COS;
Permit ();
if (!CliStdout)
{
printf ("Invalid CLI.\n", CliNumber);
exit ( EXIT_FAILURE );
}
}
break;
default:
printf ("Usage: %s [-av] [-c <cli>].\n", argv[0]);
exit (EXIT_FAILURE);
}
if (!(HaltBase = OpenLibrary ("halt.library", 0)))
{
printf ("Failed to open halt.library.\n");
return EXIT_FAILURE;
}
if (CliNumber)
{
if (!OpenTimerDevice ())
{
printf ("Failed to open timer.device.\n");
CloseLibrary (HaltBase);
return EXIT_FAILURE;
}
}
if (prt = CreateMsgPort ())
{
mask = 1 << prt -> mp_SigBit;
mask |= SIGBREAKF_CTRL_C;
mask |= TimerMask;
if (AddShutdownPort (prt))
{
while (1)
{
rmask = Wait (mask);
if (rmask & TimerMask)
StartTimer ();
if (sm = (ShutdownMessage *) GetMsg (prt))
{
switch (sm -> sm_Status)
{
case SHUTDOWN_WARN:
printf ("The system is going down in %d seconds.\n", sm -> sm_TimeLeft);
break;
case SHUTDOWN_INFO:
if (verbose)
{
if (sm -> sm_Info == SDMI_UPS_MONITOR)
{
printf ("Shutdown info received:\n");
ups = sm -> sm_Extra;
if (ups -> ui_Event > UPS_EV_MAX)
printf ("Event = %d (unknown)\n", ups -> ui_Event);
else
printf ("Event = %s.\n", UpsEvents[ups -> ui_Event]);
printf ("Charge = %d.\n", ups -> ui_Charge);
printf ("Remaining time = %d.\n", ups -> ui_Time);
}
else
printf ("Shutdown info received.\n");
}
break;
case SHUTDOWN_ABORT:
printf ("Shutdown has been aborted.\n");
#if 0
CloseTimerDevice ();
RemShutdownPort (prt);
ReplyMsg ((struct Message *) sm);
while (sm = GetMsg (prt))
ReplyMsg ((struct Message *) sm);
DeleteMsgPort (prt);
CloseLibrary (HaltBase);
exit (EXIT_SUCCESS);
#else
break;
#endif
case SHUTDOWN_UMOUNT:
printf ("The system is going down, unmounting filesystems.\n");
break;
case SHUTDOWN_NOW:
printf ("The system is going down in 5 seconds.\n");
break;
case SHUTDOWN_HALT:
printf ("The system is halted.\n");
break;
default:
printf ("Unknown message.\n");
break;
}
if (abort)
sm -> sm_Flags |= SDMF_CANCEL;
ReplyMsg ((struct Message *) sm);
}
if (rmask & SIGBREAKF_CTRL_C || !CheckCLISession ())
{
if (rmask & SIGBREAKF_CTRL_C)
printf ("CTRL-C\n");
else
printf ("\n%s: End of session.\n", argv[0]);
RemShutdownPort (prt);
break;
}
}
}
else
printf ("AddShutdownPort() failed.\n");
while (sm = GetMsg (prt))
ReplyMsg ((struct Message *) sm);
DeleteMsgPort (prt);
}
else
printf ("Can't allocate message port.\n");
CloseTimerDevice ();
CloseLibrary (HaltBase);
MyProc -> pr_WindowPtr = WindowPtr;
exit ( EXIT_SUCCESS );
}